return impl_repo_remote_delete (self, NULL, FALSE, name, cancellable, error);
}
+
+static gboolean
+impl_repo_remote_replace (OstreeRepo *self,
+ GFile *sysroot,
+ const char *name,
+ const char *url,
+ GVariant *options,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_return_val_if_fail (name != NULL, FALSE);
+ g_return_val_if_fail (url != NULL, FALSE);
+ g_return_val_if_fail (options == NULL || g_variant_is_of_type (options, G_VARIANT_TYPE ("a{sv}")), FALSE);
+
+ if (!ostree_validate_remote_name (name, error))
+ return FALSE;
+
+ g_autoptr(GError) local_error = NULL;
+ g_autoptr(OstreeRemote) remote = _ostree_repo_get_remote (self, name, &local_error);
+ if (remote == NULL)
+ {
+ if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
+ {
+ g_propagate_error (error, g_steal_pointer (&local_error));
+ return FALSE;
+ }
+ g_clear_error (&local_error);
+ if (!impl_repo_remote_add (self, sysroot, FALSE, name, url, options,
+ cancellable, error))
+ return FALSE;
+ }
+ else
+ {
+ /* Replace the entire option group */
+ if (!g_key_file_remove_group (remote->options, remote->group, error))
+ return FALSE;
+
+ if (g_str_has_prefix (url, "metalink="))
+ g_key_file_set_string (remote->options, remote->group, "metalink",
+ url + strlen ("metalink="));
+ else
+ g_key_file_set_string (remote->options, remote->group, "url", url);
+
+ if (options != NULL)
+ keyfile_set_from_vardict (remote->options, remote->group, options);
+
+ /* Write out updated settings */
+ if (remote->file != NULL)
+ {
+ gsize length;
+ g_autofree char *data = g_key_file_to_data (remote->options, &length,
+ NULL);
+
+ if (!g_file_replace_contents (remote->file, data, length,
+ NULL, FALSE, 0, NULL,
+ cancellable, error))
+ return FALSE;
+ }
+ else
+ {
+ g_autoptr(GKeyFile) config = ostree_repo_copy_config (self);
+
+ /* Remove the existing group if it exists */
+ if (!g_key_file_remove_group (config, remote->group, &local_error))
+ {
+ if (!g_error_matches (local_error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_GROUP_NOT_FOUND))
+ {
+ g_propagate_error (error, g_steal_pointer (&local_error));
+ return FALSE;
+ }
+ }
+
+ ot_keyfile_copy_group (remote->options, config, remote->group);
+ if (!ostree_repo_write_config (self, config, error))
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
/**
* ostree_repo_remote_change:
* @self: Repo
case OSTREE_REPO_REMOTE_CHANGE_DELETE_IF_EXISTS:
return impl_repo_remote_delete (self, sysroot, TRUE, name,
cancellable, error);
+ case OSTREE_REPO_REMOTE_CHANGE_REPLACE:
+ return impl_repo_remote_replace (self, sysroot, name, url, options,
+ cancellable, error);
}
g_assert_not_reached ();
}
throw new Error("assertion failed " + JSON.stringify(a) + " != " + JSON.stringify(b));
}
-print('1..6')
+print('1..9')
let remotesDir = Gio.File.new_for_path('remotes.d');
remotesDir.make_directory(null);
let remoteConfigFile = remotesDir.get_child('foo.conf')
remoteConfig.save_to_file(remoteConfigFile.get_path())
+let remoteOptions = GLib.Variant.new('a{sv}', {
+ 'branches': GLib.Variant.new('as', ['test']),
+});
+
// Use the full Repo constructor to set remotes-config-dir
let repoFile = Gio.File.new_for_path('repo');
let repo = new OSTree.Repo({path: repoFile,
// Adding a remote should not go in the remotes.d dir unless this is a
// system repo or add-remotes-config-dir is set to true
-repo.remote_add('bar', 'http://bar', null, null);
+repo.remote_add('bar', 'http://bar', remoteOptions, null);
remotes = repo.remote_list()
assertNotEquals(remotes.indexOf('bar'), -1);
assertEquals(remotesDir.get_child('bar.conf').query_exists(null), false);
repoConfig.set_boolean('core', 'add-remotes-config-dir', true);
repo.write_config(repoConfig);
repo.reload_config(null);
-repo.remote_add('baz', 'http://baz', null, null);
+repo.remote_add('baz', 'http://baz', remoteOptions, null);
remotes = repo.remote_list()
assertNotEquals(remotes.indexOf('baz'), -1);
assertEquals(remotesDir.get_child('baz.conf').query_exists(null), true);
}
print("ok config-remote-in-config-dir-fails");
+
+// Replacing a non-existent remote should succeed. This should go in the
+// config dir since add-remote-config-dir is set to true above
+repo.remote_change(null, OSTree.RepoRemoteChange.REPLACE,
+ 'nonexistent', 'http://nonexistent',
+ null, null);
+remotes = repo.remote_list();
+assertNotEquals(remotes.indexOf('nonexistent'), -1);
+assertEquals(remotesDir.get_child('nonexistent.conf').query_exists(null), true);
+
+print("ok replace-missing-remote-succeeds");
+
+// Test replacing remote options in config dir. This should remove the
+// branches setting above
+repo.remote_change(null, OSTree.RepoRemoteChange.REPLACE, 'baz',
+ 'http://baz2', null, null);
+remoteConfigFile = remotesDir.get_child('baz.conf');
+remoteConfig = GLib.KeyFile.new();
+remoteConfig.load_from_file(remoteConfigFile.get_path(),
+ GLib.KeyFileFlags.NONE);
+assertEquals(remoteConfig.get_value('remote "baz"', 'url'), 'http://baz2');
+try {
+ remoteConfig.get_string_list('remote "baz"', 'branches');
+ throw new Error('baz remote should not have branches option');
+} catch (e) {
+ if (!(e.matches(GLib.KeyFileError, GLib.KeyFileError.KEY_NOT_FOUND)))
+ throw e;
+}
+
+print("ok replace-remote-in-config-dir");
+
+// Test replacing remote options in config file. This should remove the
+// branches setting above
+repo.remote_change(null, OSTree.RepoRemoteChange.REPLACE, 'bar',
+ 'http://bar2', null, null);
+repoConfig = repo.get_config();
+assertEquals(repoConfig.get_value('remote "bar"', 'url'), 'http://bar2');
+try {
+ repoConfig.get_string_list('remote "bar"', 'branches');
+ throw new Error('bar remote should not have branches option');
+} catch (e) {
+ if (!(e.matches(GLib.KeyFileError, GLib.KeyFileError.KEY_NOT_FOUND)))
+ throw e;
+}
+
+print("ok replace-remote-in-config-file");